package com.example.WebSocketDemo.socket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.example.WebSocketDemo.bean.FriendRequest;
import com.example.WebSocketDemo.bean.Message;
import com.example.WebSocketDemo.service.FriendRequestService;
import com.example.WebSocketDemo.service.MessageService;
import com.example.WebSocketDemo.service.RecentMessageService;
import com.example.WebSocketDemo.service.impl.FriendRequestImpl;
import com.example.WebSocketDemo.service.impl.MessageServiceImpl;
import com.example.WebSocketDemo.service.impl.RecentMessageServiceImpl;
import com.example.WebSocketDemo.util.ApplicationContextRegister;

import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;


import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static java.lang.Thread.sleep;

@Component
@ServerEndpoint("/websocket/{username}")

public class WebSocket {
   // private RecentMessageService recentMessageService;
    private MessageService messageService;
    private FriendRequestService friendRequestService;
    /**
     * 在线人数
     */
    public static int onlineNumber = 0;
    /**
     * 以用户的姓名为key，WebSocket为对象保存起来
     */
    private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
    /**
     * 会话
     */
    private Session session;
    /**
     * 用户名称
     */
    private String username;

    /**
     * OnOpen 表示有浏览器链接过来的时候被调用
     * OnClose 表示浏览器发出关闭请求的时候被调用
     * OnMessage 表示浏览器发消息的时候被调用
     * OnError 表示有错误发生，比如网络断开了等等
     */

    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) throws IOException {
        onlineNumber++;
        //System.out.println("现在来连接的客户id：" + session.getId() + "用户名：" + username);
        this.username = username;
        this.session = session;
        //System.out.println("有新连接加入！ 当前在线人数" + onlineNumber);
        //messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
        //先给所有人发送通知，说我上线了
        Map<String, Object> map1 = new HashMap<>();
        map1.put("messageType", 1);
        map1.put("username", username);
        //sendMessageAll(JSON.toJSONString(map1), username);

        //把自己的信息加入到map当中去
        clients.put(username, this);
        //给自己发一条消息：告诉自己现在都有谁在线
        Map<String, Object> map2 = new HashMap<>();
        map2.put("messageType", 3);
        //移除掉自己
        Set<String> set = clients.keySet();
        map2.put("onlineUsers", set);
        //sendMessageTo(JSON.toJSONString(map2), username);
      //  System.out.println(JSON.toJSONString(map2));

        //把用户不在线收到的消息发给他
        ApplicationContext act =  ApplicationContextRegister.getApplicationContext();
        messageService = act.getBean(MessageServiceImpl.class);
        List<Message> unreadMsgList = messageService.getUnAcceptedMessage(username);
        //System.out.println(unreadMsgList);
          //System.out.println(username+":正在接收消息......");
        for(Message message:unreadMsgList){
            //System.out.println(message);
            Map<String, Object> mapUnread = new HashMap<>();
            mapUnread.put("chatType",message.getChatType());
            mapUnread.put("fromUser",message.getFromUser());
            mapUnread.put("id",-1);
            mapUnread.put("messageContent",message.getMessageContent());
            mapUnread.put("messageType",message.getMessageType());
            mapUnread.put("toUser",message.getToUser());
            mapUnread.put("profilePhoto",message.getProfilePhoto());
            mapUnread.put("nickname",message.getNickname());
            mapUnread.put("sendTime",message.getSendTime());
            Map<String, Object> mapUnread2 = new HashMap<>();
            mapUnread2.put("textMessage",JSON.toJSONString(mapUnread));
            sendMessageToDontOnline(JSON.toJSONString(mapUnread2), username);
        }
      //  System.out.println(username+":接收消息完毕");


        friendRequestService = act.getBean(FriendRequestImpl.class);
        List<FriendRequest> unReadRequestList = friendRequestService.getUnAcceptedRequest(username);
        System.out.println(unReadRequestList);
        for(FriendRequest friendRequest:unReadRequestList){
            Map<String, Object> mapUnread4 = new HashMap<>();
            mapUnread4.put("messageType",1);
            mapUnread4.put("messageContent",friendRequest.getMessage());
            Map<String, Object> mapUnread5 = new HashMap<>();
            mapUnread5.put("textMessage",JSON.toJSONString(mapUnread4));
            sendRequestToDontOnline(JSON.toJSONString(mapUnread5), username);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("服务端发生了错误" + error.getMessage());
        //error.printStackTrace();
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        onlineNumber--;
        //webSockets.remove(this);
        clients.remove(username);
        //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
        Map<String, Object> map1 = new HashMap<>();
        map1.put("messageType", 2);
        map1.put("onlineUsers", clients.keySet());
        map1.put("username", username);
        // sendMessageAll(JSON.toJSONString(map1), username);
      //  System.out.println(JSON.toJSONString(map1));
       // System.out.println("有连接关闭！ 当前在线人数" + onlineNumber);
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        ApplicationContext act =  ApplicationContextRegister.getApplicationContext();
        messageService = act.getBean(MessageServiceImpl.class);
        try {
          //  System.out.println("OnMessage");
           // System.out.println("来自客户端消息：" + message + "客户端的id是：" + session.getId());
            JSONObject jsonObject = JSON.parseObject(message);
            String textMessage = jsonObject.getString("message");
            JSONObject jsonObject2 = JSON.parseObject(textMessage);
            String textMessage2 = jsonObject2.getString("messageContent");
            String fromusername = jsonObject.getString("username");
            String tousername = jsonObject.getString("to");
            //System.out.println(jsonObject.toJSONString());
          //  System.out.println(msgType);
            //System.out.println("textMessage");
            //System.out.println(textMessage);
            //System.out.println("textMessage2");
            //System.out.println(textMessage2);
            int msgType = jsonObject2.getInteger("messageType");

            if(msgType == 0){
                JSONObject jsonObject3 = JSON.parseObject(textMessage2);
                //textMessage2 = jsonObject3.getString("message");
                //System.out.println(textMessage2);
                //JSONObject jsonObject4 = JSON.parseObject(textMessage2);
                int messageType = jsonObject3.getInteger("types");
                String messageContent = jsonObject3.getString("message");
                String sendTime = jsonObject3.getString("time");
                //System.out.println(sendTime);
                //如果不是发给所有，那么就发给某一个人
                //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
                Map<String, Object> map1 = new HashMap<>();
                map1.put("messageType", 4);
                map1.put("textMessage", textMessage);
                map1.put("fromusername", fromusername);
                Message newMsg = new Message();
                newMsg.setFromUser(fromusername);
                newMsg.setSendTime(sendTime);
                // System.out.println(tousername);

                newMsg.setMessageContent(messageContent);
                newMsg.setMessageType(messageType);

                if (tousername.equals("All")) {
                    map1.put("tousername", "All");
                    newMsg.setToUser("All");
                    newMsg.setChatType("public");
                    sendMessageAll(JSON.toJSONString(map1), fromusername);
                } else {
                    map1.put("tousername", tousername);
                    newMsg.setToUser(tousername);
                    newMsg.setChatType("private");
                    sendMessageTo(JSON.toJSONString(map1),newMsg ,tousername);
                }
                //recentMessageService = act.getBean(RecentMessageServiceImpl.class);
                // recentMessageService.updateRecentMessage(textMessage,"liuxiao","luowenyang");
            }
            else if(msgType == 1){
                //好友请求
                Map<String, Object> map2 = new HashMap<>();
                map2.put("messageType", 4);
                map2.put("textMessage", textMessage);
                map2.put("fromusername", fromusername);
                sendMessageRequestTo(JSON.toJSONString(map2),fromusername ,tousername);
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("发生了错误了");
        }
    }
    public void sendMessageRequestTo(String message ,String fromUserName,String ToUserName) throws IOException {
        ApplicationContext act =  ApplicationContextRegister.getApplicationContext();
        friendRequestService = act.getBean(FriendRequestImpl.class);
        // System.out.println("sendMessageTo");
        // System.out.println(message+ToUserName);
        for (WebSocket item : clients.values()) {
            if (item.username.equals(ToUserName)) {
                //  System.out.println("发送了消息！");
                item.session.getAsyncRemote().sendText(message);
                return;
            }
        }
        //用户不在线 保存消息
        // System.out.println("用户不在线！！");

        //将好友请求的accepted字段修改为0
        friendRequestService.userDontLine(fromUserName,ToUserName);

    }

    public void sendMessageTo(String message,Message msg ,String ToUserName) throws IOException {
        ApplicationContext act =  ApplicationContextRegister.getApplicationContext();
        //recentMessageService = act.getBean(RecentMessageServiceImpl.class);
        messageService = act.getBean(MessageServiceImpl.class);
       // System.out.println("sendMessageTo");
       // System.out.println(message+ToUserName);
        for (WebSocket item : clients.values()) {
            if (item.username.equals(ToUserName)) {
              //  System.out.println("发送了消息！");
                item.session.getAsyncRemote().sendText(message);
                //System.out.println(msg);
                messageService.insertMessage(msg);
                return;
            }
        }
        //用户不在线 保存消息
       // System.out.println("用户不在线！！");
       messageService.insertUnReadMessage(msg);
       // recentMessageService.updateUnreadMessageCount("liuxiao","luowenyang");
    }

    //用户不在线推送消息
    public void sendMessageToDontOnline(String message,String ToUserName) throws IOException {
        ApplicationContext act =  ApplicationContextRegister.getApplicationContext();
//        recentMessageService = act.getBean(RecentMessageServiceImpl.class);
        messageService = act.getBean(MessageServiceImpl.class);
        messageService.updateUnReadMessage(ToUserName);
        for (WebSocket item : clients.values()) {
            if (item.username.equals(ToUserName)) {
                item.session.getBasicRemote().sendText(message);
                return;
            }
        }
    }

    public void sendRequestToDontOnline(String message,String ToUserName) throws IOException {
        ApplicationContext act =  ApplicationContextRegister.getApplicationContext();
//        recentMessageService = act.getBean(RecentMessageServiceImpl.class);
        friendRequestService = act.getBean(FriendRequestImpl.class);
        friendRequestService.changeRequestAccepted(ToUserName);
        //System.out.println(message);
        for (WebSocket item : clients.values()) {
            if (item.username.equals(ToUserName)) {
                item.session.getBasicRemote().sendText(message);
                return;
            }
        }
    }

    public void sendMessageAll(String message, String FromUserName) throws IOException {

       // System.out.println("sendMessageAll");
       // System.out.println(message);
        for (WebSocket item : clients.values()) {
            if(!item.username.equals(FromUserName))
                item.session.getAsyncRemote().sendText(message);
            }


    }

    public void DealAddFriendRequest(String message, String FromUserName,String toUserName){

    }

    public static synchronized int getOnlineCount() {
        return onlineNumber;
    }

}